package com.luyi.sensor.entity;

import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * SerialNoTest流水号生成：“LSH”+yyyyMMdd+6位数字，共17位
 * author: luyi
 * time: 2022/1/10 20:57
 */

public class SerialCode extends Thread{

//    @Value("")
//    public static final String prefix;

    public static void main(String[] args) {
        String serialNo = createSerialCode();
        String serialNo2 = createSerialCode();
        String serialNo3 = createSerialCode();
        String serialNo4 = createSerialCode();
        String serialNo5 = createSerialCode();
        String serialNo6 = createSerialCode();
        String serialNo7 = createSerialCode();
        String serialNo8 = createSerialCode();
        System.out.println("生成的流水号:"+serialNo);
        System.out.println("生成的流水号:"+serialNo2);
        System.out.println("生成的流水号:"+serialNo3);
        System.out.println("生成的流水号:"+serialNo4);
        System.out.println("生成的流水号:"+serialNo5);
        System.out.println("生成的流水号:"+serialNo6);
        System.out.println("生成的流水号:"+serialNo7);
        System.out.println("生成的流水号:"+serialNo8);

        System.out.println(System.currentTimeMillis());
    }

    /**
     * 生成17位唯一流水号，"LSH"+yyyyMMdd+6位数字
     * 6位数字，如：000001
     * @return
     */
    private static String createSerialCode(){
        String todayDate = new SimpleDateFormat("yyyyMMdd").format(new Date());//先查询到今天的日期，格式:"yyyyMMdd"

        //固定字母前缀 拼接 今天日期，组成新的完整的前缀，也就是缓存的key
        String cacheKey = "LSH"+todayDate;


        return getCodeOfSix(cacheKey, getSeconds());//流水号 = 缓存key + 拼接的数值 = 前缀 + 日期 + 拼接的数值
    }


    /**
     * 将数值拼接成对应的位数
     * @param prefix  前缀："LSH"+yyyyMMdd
     * @param nowNum  当前要生成的数字
     * @return 拼接好的流水号
     */
    public static String getCodeOfSix(String prefix,int nowNum ) {

        StringBuilder codeSb = new StringBuilder();//拼接结果
        StringBuilder numSb = new StringBuilder();//需要拼接的数字

        //封装的数字对象，里面 value 加了 volatile关键字，保证了线程安全
        AtomicInteger count = new AtomicInteger(nowNum); //AtomicInteger用于原子递增计数器等应用程序

        //将数值补足为6位字符串
        if (count.get() < 10) {
            numSb.append("00000").append(count.get());
        } else if(count.get() < 100){
            numSb.append("0000").append(count.get());
        }else if(count.get() < 1000){
            numSb.append("000").append(count.get());
        }else if(count.get() < 10000){
            numSb.append("00").append(count.get());
        }else if(count.get() < 100000){
            numSb.append("0").append(count.get());
        } else if (count.get() >= 100000) {
            numSb.append(count.get());
        }

        codeSb.append(prefix);//先拼接前缀
        codeSb.append(numSb);//再拼接数字
        return codeSb.toString();
    }


    /**
     * 获取当天结束还剩余多少秒
     * @return
     */
    public static int getSeconds(){
        Calendar curDate = Calendar.getInstance();//获取今天当前时间

		//获取明天凌晨0点的日期
        Calendar tommorowDate = new GregorianCalendar(curDate.get(Calendar.YEAR),curDate.get(Calendar.MONTH),curDate.get(Calendar.DATE) + 1,//年-月-日
                                                                                   0, 0, 0);//时-分-秒

        return (int)(tommorowDate.getTimeInMillis() - curDate.getTimeInMillis()) / 1000;//返回 明天凌晨0点 和 今天当前时间 的差值（秒数）
    }
}
